//
// Created by lymk on 2021/8/12.
//

#include "ItemActor.h"

PicData *ItemActor::getPicData() const {
    return picData;
}

void ItemActor::setPicData(PicData *picData) {
    ItemActor::picData = picData;
}

const GMath::Vec2 &ItemActor::getRenderPos() const {
    return renderPos;
}

void ItemActor::setRenderPos(const GMath::Vec2 &renderPos) {
    ItemActor::renderPos = renderPos;
}

const GMath::Vec2 &ItemActor::getCollidePos() const {
    return collidePos;
}

void ItemActor::setCollidePos(const GMath::Vec2 &collidePos) {
    ItemActor::collidePos = collidePos;
}

const GMath::Vec2 &ItemActor::getCollideSize() const {
    return collideSize;
}

void ItemActor::setCollideSize(const GMath::Vec2 &collideSize) {
    ItemActor::collideSize = collideSize;
}

float ItemActor::getFallSpeed() const {
    return fallSpeed;
}

void ItemActor::setFallSpeed(float fallSpeed) {
    ItemActor::fallSpeed = fallSpeed;
}

void ItemActor::Initialize(std::string path,GMath::Vec2 initPos,float speed,float iscore) {
    PicData tmp = LoadPNG(path);
    if(tmp.data != nullptr){
        picData = new PicData();
        *picData = tmp;
    }else{
        picData = nullptr;
    }
    renderPos = initPos;
    collidePos = {renderPos.X + picData->width/4,renderPos.Y + picData->height/4};
    collideSize = {static_cast<float>(picData->width/2),static_cast<float>(picData->height/2)};
    fallSpeed = speed;
    bFall = true;
    score = iscore;
    bShouldDestory = false;
    bDelayDestory = false;
}

void ItemActor::Update(double DeltaSeconds, RenderUtils renderUtils, PhyComponent *worldCollide) {
    if(bFall)
        HandleFall(DeltaSeconds,worldCollide);
    HandleRender(renderUtils);
    if(!bFall){
        if(bDelayDestory){
            delayCool->Update(DeltaSeconds);
            if(delayCool->GetFlag())
                bShouldDestory = true;
        }else{
            bShouldDestory = true;
        }
    }
}

GMath::Rectangle ItemActor::getCollideBox() {
    GMath::Rectangle res = {collidePos,collidePos+collideSize};
    return res;
}

void ItemActor::HandleFall(double DeltaSeconds, PhyComponent *worldCollide) {
    float tmpX = collidePos.X;
    float tmpY = collidePos.Y + DeltaSeconds*fallSpeed;
    ItemActor* actor = worldCollide->PreViewCollide({tmpX,tmpY,tmpX+collideSize.X,tmpY+collideSize.Y});
    if(actor!= nullptr&&actor->getPicData() == nullptr){
        bFall = false;
    }else{
        renderPos.Y += DeltaSeconds*fallSpeed;
        collidePos.Y = tmpY;
    }
}

void ItemActor::HandleRender(RenderUtils renderUtils) {
    BITMAPINFO bmInfo;
    memset(&bmInfo.bmiHeader, 0, sizeof(BITMAPINFOHEADER));
    bmInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmInfo.bmiHeader.biWidth = picData->width;
    bmInfo.bmiHeader.biHeight = -1*picData->height;
    bmInfo.bmiHeader.biPlanes = 1;
    bmInfo.bmiHeader.biBitCount = picData->nrChannels * 8;//32位位图支持透明度
    //int tmpx = 0,tmpy = 0;
    SetDIBitsToDevice(renderUtils.tmpDC, renderPos.X, renderPos.Y, picData->width, picData->height,
                      0, 0, 0, picData->height, picData->data, &bmInfo, 0);
    //BitBlt(PDC,0,0,width,height,tmpDC,0,0,SRCPAINT);
    BLENDFUNCTION bf = {0};
    bf.BlendOp = AC_SRC_OVER;
    bf.BlendFlags = 0;
    bf.AlphaFormat = 1;
    bf.SourceConstantAlpha = 255;
    AlphaBlend(renderUtils.bufDC,0,0,renderUtils.dcWidth,renderUtils.dcHeight,renderUtils.tmpDC,0,0,
               renderUtils.dcWidth,renderUtils.dcHeight,bf);
}

ItemActor::ItemActor() {
    picData = nullptr;
}

bool ItemActor::isBFall() const {
    return bFall;
}

void ItemActor::setBFall(bool bFall) {
    ItemActor::bFall = bFall;
}

void ItemActor::Finalize() {
    if(picData != nullptr){
        delete picData;
        picData = nullptr;
    }

}

float ItemActor::getScore() const {
    return score;
}

void ItemActor::setScore(float score) {
    ItemActor::score = score;
}

bool ItemActor::isBShouldDestory() const {
    return bShouldDestory;
}

void ItemActor::setBShouldDestory(bool bShouldDestory) {
    ItemActor::bShouldDestory = bShouldDestory;
}

void
ItemActor::Initialize(std::string path, GMath::Vec2 initPos, float speed, float iscore, bool delay, float delayTime) {
    Initialize(path,initPos,speed,iscore);
    bDelayDestory = delay;
    delayCool = new CoolUtil(delayTime);
}
